package com.bensonbasement.snorflux.server.world;

import java.util.List;

import com.bensonbasement.snorflux.memory.EntityInfo;
import com.bensonbasement.snorflux.memory.WorldElementInfo;
import com.bensonbasement.snorflux.server.verbs.Verb;
import com.bensonbasement.snorflux.server.world.prototypes.EntityPrototype;
import com.bensonbasement.snorflux.server.world.prototypes.WorldElementPrototype;

public abstract class Entity extends WorldElement {

	public Entity(World world, EntityPrototype prototype) {
		super(world, prototype);
		// TODO Auto-generated constructor stub
	}
	
	protected EntityPrototype getPrototype() {
		return (EntityPrototype) super.getPrototype();
	}
	
	public Level getLevel() {
		if (this.getLocation() == null) {
			return null;
		}
		else {
			return this.getLocation().getLevel();
		}
	}
	
	public Space getSpace() {
		return this.getLocation().getSpace();
	}
	
	public Verb getVerb(String verbName) {
		return this.getPrototype().getVerb(verbName);
	}
	
	public List<Verb> getAllVerbs() {
		return getPrototype().getAllVerbs();
	}
	
	final protected void setLocationHelper(ILocation newLocation) {
		ILocation oldLocation = this.getLocation();
		if (newLocation != oldLocation) {
			Level newLevel;
			Level oldLevel;
			if (oldLocation == null) {
				oldLevel = null;
			}
			else {
				oldLevel = oldLocation.getLevel();
				this.removeSelfFrom(oldLocation);
			}
			if (newLocation == null) {
				newLevel = null;
			}
			else {
				newLevel = newLocation.getLevel();
				this.addSelfTo(newLocation);
			}
			this.actuallySetLocation(newLocation);
			this.triggerInfoRefresh(oldLevel);
		}
	}
	
	protected abstract void addSelfTo(ILocation location);
	protected abstract void removeSelfFrom(ILocation location);
	protected abstract void actuallySetLocation(ILocation location);
	
	public abstract ILocation getLocation();
	
	public abstract EntityInfo render(IViewer viewer);
}
